package com.pignest.hotel.dao.hibernate;

import java.sql.SQLException;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.pignest.framework.dao.BaseHibernateDao;
import com.pignest.hotel.beans.Booking;
import com.pignest.hotel.beans.BookingRoom;
import com.pignest.hotel.beans.Room;
import com.pignest.hotel.dao.BookingDao;
import com.pignest.hotel.definition.BookingStatus;

@SuppressWarnings("unchecked")
public class BookingHibernateDao extends BaseHibernateDao implements BookingDao {

	public List<Booking> query(final String name, final String phone, final BookingStatus status) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				boolean hasName = StringUtils.isNotEmpty(name);
				boolean hasPhone = StringUtils.isNotEmpty(phone);
				boolean hasStatus = status != null;
				StringBuilder hql = new StringBuilder("from Booking as b");
				if (hasName || hasPhone || hasStatus) {
					hql.append(" where");
					if (hasName)
						hql.append(" b.name like :name and");
					if (hasPhone)
						hql.append(" b.phone like :phone and");
					if (hasStatus)
						hql.append(" b.status=:status and");
					hql.setLength(hql.length() - 3);
				}
				Query q = session.createQuery(hql.toString());
				if (hasName)
					q.setString("name", '%' + name.replaceAll("%", "%%") + '%');
				if (hasPhone)
					q.setString("phone", '%' + phone + '%');
				if (hasStatus)
					q.setString("status", status.name());
				return q.list();
			}
		});
	}

	public List<Booking> query(final Date startTime, final Date endTime) {
		return getHibernateTemplate().executeFind(new HibernateCallback() {
			
			@Override
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				StringBuilder hql = new StringBuilder("from Booking as b");
				if (startTime != null && endTime != null) {
					hql.append(" where");
					if (startTime != null)
						hql.append(" time >= :startTime and");
					if (endTime != null)
						hql.append(" time < :endTime and");
					hql.setLength(hql.length() - 3);
				}
				Query q = session.createQuery(hql.toString());
				if (startTime != null)
					q.setDate("startTime", startTime);
				if (endTime != null)
					q.setDate("endTime", endTime);
				return q.list();
			}
		});
	}

	public Booking getBookingByRoom(Room room) {
		String hql = "from BookingRoom as o where o.status=? and o.booking.status=? and o.room=?";
		Object[] params = new Object[] {BookingStatus.ONGOING.name(), BookingStatus.ONGOING.name(), room};
		List<BookingRoom> br = getHibernateTemplate().find(hql, params);
		if (br == null || br.isEmpty())
			return null;
		return br.get(0).getBooking();
	}

}
